﻿Imports System.Xml
Imports System.IO
Imports System.Text
''' <summary>
''' 共通方法
''' </summary>
''' <remarks></remarks>
Public Module CommonMethod
#Region "常量"
    ''' <summary>
    ''' 测试模式[调试用，和业务逻辑无关]
    ''' </summary>
    ''' <remarks></remarks>
    Public TestMode As Boolean = True
    ''' <summary>
    ''' PIC在行里的位置
    ''' </summary>
    ''' <remarks></remarks>
    Public Const PICPosition As Byte = 39
    ''' <summary>
    ''' VALUE在行里的位置
    ''' </summary>
    ''' <remarks></remarks>
    Public Const VALUEPosition As Byte = 51
    ''' <summary>
    ''' 左边界
    ''' </summary>
    ''' <remarks></remarks>
    Public LeftStart As Byte = 7
    ''' <summary>
    ''' 右边界
    ''' </summary>
    ''' <remarks></remarks>
    Public RightEnd As Byte = 71
    ''' <summary>
    ''' 缩进格数
    ''' </summary>
    ''' <remarks></remarks>
    Public Const Indent As Byte = 3
    ''' <summary>
    ''' Z/OS 上面的NOT符号 
    ''' </summary>
    ''' <remarks></remarks>
    Public NotChar As String = Text.Encoding.Unicode.GetString(New Byte() {241, 248})
    ''' <summary>
    ''' 为Multip方法添加ON SIZE ERROR
    ''' </summary>
    ''' <remarks></remarks>
    Public OnSizeErrorForMultip As Boolean = False
    ''' <summary>
    ''' 为Devide方法添加ON SIZE ERROR
    ''' </summary>
    ''' <remarks></remarks>
    Public OnSizeErrorForDevide As Boolean = False
    ''' <summary>
    ''' 为Compute方法添加ON SIZE ERROR
    ''' </summary>
    ''' <remarks></remarks>
    Public OnSizeErrorForCompute As Boolean = False
    ''' <summary>
    ''' 为Compute方法添加ON SIZE ERROR
    ''' </summary>
    ''' <remarks></remarks>
    Public AddContinueForEmptyElse As Boolean = False
    ''' <summary>
    ''' 用户设定
    ''' </summary>
    ''' <remarks></remarks>
    Public MyConfig As clsConfig
#End Region
#Region "结构和枚举"
    ''' <summary>
    ''' 转换结果
    ''' </summary>
    ''' <remarks></remarks>
    Enum ConversionResult
        OK
        FileNotFound
        Exception
    End Enum
    ''' <summary>
    ''' 文件结构
    ''' </summary>
    ''' <remarks></remarks>
    Structure FileInfoRec
        ''' <summary>
        ''' 程序名
        ''' </summary>
        ''' <remarks></remarks>
        Dim ProgID As String
        ''' <summary>
        ''' 文件名称
        ''' </summary>
        ''' <remarks></remarks>
        Dim FileID As String
        ''' <summary>
        ''' 长度
        ''' </summary>
        ''' <remarks></remarks>
        Dim Length As Integer
        ''' <summary>
        ''' 定长或可变长文件
        ''' </summary>
        ''' <remarks></remarks>
        Dim RECFM As enmRECFM
        ''' <summary>
        ''' 输入输出类型
        ''' </summary>
        ''' <remarks></remarks>
        Dim IO As enmIO
        ''' <summary>
        ''' 是否为外部文件
        ''' </summary>
        ''' <remarks></remarks>
        Dim IsExternal As Boolean
        ''' <summary>
        ''' 是否为VSAM文件
        ''' </summary>
        ''' <remarks></remarks>
        Dim IsVSAM As Boolean
        ''' <summary>
        ''' VSAM的文件访问方式
        ''' </summary>
        ''' <remarks></remarks>
        Dim AccessMode As enmAccessMode
        ''' <summary>
        ''' VSAM的文件组织形式
        ''' </summary>
        ''' <remarks></remarks>
        Dim Orangization As enmOrganization
        ''' <summary>
        ''' VSAM的文件Key
        ''' </summary>
        ''' <remarks></remarks>
        Dim RecordKey As String
    End Structure
    ''' <summary>
    ''' 文件结构
    ''' </summary>
    ''' <remarks></remarks>
    Structure CopyBookInfoRec
        ''' <summary>
        ''' Copy句名称
        ''' </summary>
        ''' <remarks></remarks>
        Dim CopyBookName As String
        ''' <summary>
        ''' 是否使用
        ''' </summary>
        ''' <remarks></remarks>
        Dim IsDisposed As Boolean
        ''' <summary>
        ''' 类型
        ''' </summary>
        ''' <remarks></remarks>
        Dim CopyBookType As enmCopyBookType
        ''' <summary>
        ''' 最初项层号
        ''' </summary>
        ''' <remarks></remarks>
        Dim FirstLayNo As Byte
        ''' <summary>
        ''' 最终项层号
        ''' </summary>
        ''' <remarks></remarks>
        Dim LastLayNo As Byte
    End Structure
    ''' <summary>
    ''' 文件类型枚举
    ''' </summary>
    ''' <remarks></remarks>
    Enum enmRECFM
        FB = 0
        VB = 1
    End Enum
    ''' <summary>
    ''' 输入输出枚举
    ''' </summary>
    ''' <remarks></remarks>
    Enum enmIO
        ''' <summary>
        ''' 输入
        ''' </summary>
        ''' <remarks></remarks>
        Input
        ''' <summary>
        ''' 输出
        ''' </summary>
        ''' <remarks></remarks>
        Output
        ''' <summary>
        ''' 输入和输出
        ''' </summary>
        ''' <remarks></remarks>
        IO
    End Enum
    ''' <summary>
    ''' VSAM文件的组织形式
    ''' </summary>
    ''' <remarks></remarks>
    Enum enmOrganization
        ''' <summary>
        ''' 顺序
        ''' </summary>
        ''' <remarks></remarks>
        SEQUENTIAL
        ''' <summary>
        ''' 索引
        ''' </summary>
        ''' <remarks></remarks>
        INDEXED
    End Enum
    ''' <summary>
    ''' VSAM文件的读取方式
    ''' </summary>
    ''' <remarks></remarks>
    Enum enmAccessMode
        ''' <summary>
        ''' 顺序
        ''' </summary>
        ''' <remarks></remarks>
        SEQUENTIAL
        ''' <summary>
        ''' 随机
        ''' </summary>
        ''' <remarks></remarks>
        RANDOM
        ''' <summary>
        ''' 动态
        ''' </summary>
        ''' <remarks></remarks>
        DYNAMIC
    End Enum
    ''' <summary>
    ''' COPY句类型
    ''' </summary>
    ''' <remarks></remarks>
    Enum enmCopyBookType
        ''' <summary>
        ''' 数据
        ''' </summary>
        ''' <remarks></remarks>
        Data
        ''' <summary>
        ''' 程序
        ''' </summary>
        ''' <remarks></remarks>
        Procedure
    End Enum
#End Region
#Region "变量"
    ''' <summary>
    ''' 日志Writer
    ''' </summary>
    ''' <remarks></remarks>
    Public LogWriter As StreamWriter
    ''' <summary>
    ''' XML文档
    ''' </summary>
    ''' <remarks></remarks>
    Public mXmlDocument As XmlDocument
    ''' <summary>
    ''' 根节点
    ''' </summary>
    ''' <remarks></remarks>
    Public RootNode As XmlNode
    ''' <summary>
    ''' 标示部
    ''' </summary>
    ''' <remarks></remarks>
    Public mIdentificationNode As IdentificationNode
    ''' <summary>
    ''' 环境部
    ''' </summary>
    ''' <remarks></remarks>
    Public mEnvironmentNode As EnvironmentNode
    ''' <summary>
    ''' 数据部
    ''' </summary>
    ''' <remarks></remarks>
    Public mDataNode As DataNode
    ''' <summary>
    ''' 手续部 
    ''' </summary>
    ''' <remarks></remarks>
    Public mProcedureNode As ProcedureNode
    ''' <summary>
    ''' 积累下来的整行注释
    ''' </summary>
    ''' <remarks></remarks>
    Public GlobalCommentList As New List(Of String)
    ''' <summary>
    ''' 原始行信息
    ''' </summary>
    ''' <remarks></remarks>
    Public PL1Source As New List(Of String)
    ''' <summary>
    ''' 嵌套深度
    ''' </summary>
    ''' <remarks></remarks>
    Public Deepth As Byte = 1
    ''' <summary>
    ''' Work变量计数
    ''' </summary>
    ''' <remarks></remarks>
    Public WK_COUNT As Integer = 1
    ''' <summary>
    ''' 文件情报的字典，Key是文件名称
    ''' </summary>
    ''' <remarks></remarks>
    Public mFileInfoDic As New Dictionary(Of String, CommonMethod.FileInfoRec)
    ''' <summary>
    ''' COPY句情报的字典，Key是COPY句名称
    ''' </summary>
    ''' <remarks></remarks>
    Public mCopyBookInfoDic As New Dictionary(Of String, CommonMethod.CopyBookInfoRec)
    ''' <summary>
    ''' 关键字列表
    ''' </summary>
    ''' <remarks></remarks>
    Public KeyWordList As New Dictionary(Of String, String)
    ''' <summary>
    ''' 保存EXEC原始文的列表
    ''' </summary>
    ''' <remarks></remarks>
    Public EXECList As New List(Of String)
#End Region
#Region "获得临时变量"
    ''' <summary>
    ''' 获得一个临时的FIXED DEC型变量的节点
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function getWorkDataFIXED_DEC(ByVal Digits As Byte, Optional ByVal factor As Byte = 0) As XmlElement
        Dim strDataName As String = "WK_PLI_I" & WK_COUNT
        Dim wkData As XmlElement = mXmlDocument.CreateElement("SINGLEDATA")
        wkData.SetAttribute("NAME", strDataName)
        wkData.SetAttribute("REPEAT", "1")
        wkData.SetAttribute("TYPE", "FIXED DEC")
        If factor = 0 Then
            wkData.SetAttribute("LENGTH", Digits)
        Else
            wkData.SetAttribute("LENGTH", Digits & "," & factor)
        End If
        If WK_COUNT = 1 Then
            Dim commentXml As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
            commentXml.SetAttribute("TEXT", "*  WK-AREA  *")
            wkData.AppendChild(commentXml)
        End If
        WK_COUNT += 1
        Return wkData
    End Function
    ''' <summary>
    ''' 获得一个字符型的临时变量
    ''' </summary>
    ''' <param name="strLength"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function getWorkDataCHAR(ByVal strLength As Integer) As XmlElement
        Dim wkData As XmlElement = mXmlDocument.CreateElement("SINGLEDATA")
        wkData.SetAttribute("NAME", "WK_PLI_I" & WK_COUNT)
        wkData.SetAttribute("REPEAT", "1")
        wkData.SetAttribute("TYPE", "CHAR")
        wkData.SetAttribute("LENGTH", strLength)
        wkData.SetAttribute("INIT", "")
        If WK_COUNT = 1 Then
            Dim commentXml As XmlElement = mXmlDocument.CreateElement("COMMENTLIST")
            commentXml.SetAttribute("TEXT", "*  WK-AREA  *")
            wkData.AppendChild(commentXml)
        End If
        WK_COUNT += 1
        Return wkData
    End Function
    ''' <summary>
    ''' 删除最后一个工作变量
    ''' </summary>
    ''' <remarks>
    ''' 可能需要维护一张新旧工作变量列表名称
    ''' 在最后出力的时候，重新整理工作变量序号
    ''' 这张表格将在LastModifyVarName方法中使用
    ''' </remarks>
    Public Sub RemoveWorkDataByName(ByVal VarName As String)
        Dim removeElement As XmlElement
        For Each mWk_node In mDataNode.WorkList
            If mWk_node.GetAttribute("NAME") = VarName Then
                removeElement = mWk_node
                mDataNode.WorkList.Remove(removeElement)
                Exit For
            End If
        Next
    End Sub
    ''' <summary>
    ''' 将两个Block合并为单个Block
    ''' </summary>
    ''' <param name="MergeInto"></param>
    ''' <param name="MergeFrom"></param>
    ''' <remarks></remarks>
    Public Sub MergeStatementBlock(ByRef MergeInto As clsStatementBlock, ByRef MergeFrom As clsStatementBlock)
        For Each subStatement As XmlElement In MergeFrom.SingleStatementList
            Select Case subStatement.Name
                Case "IF"
                    Dim mIFNode As IFNode
                    mIFNode = MergeFrom.BlockOprList(CInt(subStatement.GetAttribute("BLOCKINDEX")))
                    MergeInto.AddIF(mIFNode)
                Case "LOOP"
                    Dim mLoopNode As LoopNode
                    mLoopNode = MergeFrom.BlockOprList(CInt(subStatement.GetAttribute("BLOCKINDEX")))
                    MergeInto.AddLoop(mLoopNode)
                Case "SELECT"
                    Dim mSELECTNode As SelectNode
                    mSELECTNode = MergeFrom.BlockOprList(CInt(subStatement.GetAttribute("BLOCKINDEX")))
                    MergeInto.AddSelect(mSELECTNode)
                Case Else
                    MergeInto.AddOperation(subStatement.Clone)
            End Select
        Next
    End Sub
#End Region
End Module
